import 'dart:async';
import 'package:flutter/cupertino.dart';

import 'package:ideology/shared/widgets/code_input/config/editor_keymap.dart';
import 'package:ideology/shared/widgets/code_input/config/editor_metrics.dart';
import 'package:ideology/shared/widgets/code_input/core/editor_controller.dart';
import 'package:ideology/shared/widgets/code_input/core/text_buffer.dart';
import 'package:ideology/shared/widgets/code_input/highlight/highlight_theme.dart';
import 'package:ideology/shared/widgets/code_input/highlight/syntax_highlighter.dart';
import 'package:ideology/shared/widgets/code_input/presentation/widgets/canvas_editor.dart';
import 'package:ideology/shared/widgets/code_input/services/auto_scroller.dart';
import 'package:ideology/shared/widgets/code_input/services/boundary_detector.dart';
import 'package:ideology/shared/widgets/code_input/services/caret_blinker.dart';
import 'package:ideology/shared/widgets/code_input/services/editor_surface.dart';
import 'package:ideology/shared/widgets/code_input/services/hidden_ime_overlay.dart';
import 'package:ideology/shared/widgets/code_input/services/ime_bridge.dart';
import 'package:ideology/shared/widgets/code_input/services/indent_service.dart';
import 'package:ideology/shared/widgets/code_input/services/selection_manager.dart';
import 'package:ideology/shared/widgets/code_input/services/viewport_scroller.dart';
import 'package:ideology/shared/widgets/code_input/utils/multi_click_tracker.dart';
import 'package:ideology/shared/widgets/code_input/utils/text_layout.dart';

/// **CanvasEditorState**
///
/// - `CanvasEditor` 的状态与控制中枢：
///   - 管理文本缓冲 [TextBuffer]、光标/选区 [EditorController]；
///   - 管理输入法同步 [ImeBridge] 与隐藏输入层 [HiddenImeOverlay]；
///   - 维护多击（双击/三击）选择、缩进、自动滚动、光标闪烁等服务；
///   - 在布局变化与文本变更时确保光标可见；
///   - 将键盘快捷键映射（Tab/Shift-Tab）委托给 [EditorKeymap]；
///   - 使用 [EditorSurface] 完成命中测试、手势、绘制桥接等。
class CanvasEditorState extends State<CanvasEditor> {
  // ---- Services / Managers ---- //
  late final MultiClickTracker _multiClickTracker; // 处理双击/三击选词/选行
  final BoundaryDetector _boundary = const BoundaryDetector(); // 边界检测（坐标/拖拽）
  final IndentService _indentService = const IndentService(); // Tab/Shift-Tab 缩进服务
  late final AutoScroller _autoScroller; // 选择拖拽时的自动滚动
  final ViewportScroller _viewportScroller = const ViewportScroller(); // 计算“光标滚入可见区”的滚动量
  late final TextLayout _textLayout; // 文本测量布局（字号/行高/边距）
  late final CaretBlinker _caretBlinker; // 光标闪烁定时器
  final SelectionManager _sel = SelectionManager(); // 选区状态（是否正在选择等）

  late final TextBuffer buffer; // 文本缓冲（GapBuffer）
  late final EditorController controller; // 光标/选区控制器

  SyntaxHighlighter get _highlighter => widget.highlighter; // 语法高亮器（注入）
  HighlightTheme get _theme => widget.theme;               // 高亮主题（注入）

  final FocusNode _focusNode = FocusNode();       // 聚焦管理（IME 需要）
  late final TextEditingController _textController; // 隐藏 Editable 关联的 TextEditingController
  late final ImeBridge _imeBridge;                // 桥接 Editable 与 Buffer/Controller

  double _scrollY = 0.0;      // 纵向滚动偏移（像素）
  double _viewportHeight = 0.0; // 视口高度（像素），用于滚动计算

  EditorMetrics get _m => widget.config.metrics; // 统一读取配置的度量参数

  Timer? _autoSaveTimer; // 简易“自动保存”节流（示例用途）

  /// externalText 变更时调用：加载外部文本到本地 buffer
  void _handleExternalTextChange() {
    final txt = widget.externalText?.value;
    if (txt != null) _loadText(txt);
  }

  /// 将外部传入的整段文本载入到 [buffer] 中。
  ///
  /// - 尽量保留旧的 selection（超界则钳制）；
  /// - 仅当内容实际不同才更新 [_textController]（避免无谓的 selection 丢失或循环）。
  void _loadText(String text) {
    // 记录当前 selection（光标/选区）
    final oldSelection = _textController.selection;

    // 用 buffer 覆盖文本
    final len = buffer.length;
    if (len > 0) buffer.delete(0, len);
    if (text.isNotEmpty) buffer.insert(0, text);

    // 钳制 selection 到新文本范围
    int clamp(int v) => v.clamp(0, text.length);
    final newSelection = TextSelection(
      baseOffset: clamp(oldSelection.baseOffset),
      extentOffset: clamp(oldSelection.extentOffset),
      affinity: oldSelection.affinity,
      isDirectional: oldSelection.isDirectional,
    );

    // 仅在内容变更时更新 _textController（避免循环与 selection 抖动）
    if (_textController.text != text) {
      _textController.value = TextEditingValue(
        text: text,
        selection: newSelection,
        composing: TextRange.empty,
      );
    }

    // 同步控制器与选区
    controller.cursorPosition = newSelection.extentOffset;
    controller.clearSelection();

    // 若未聚焦则请求焦点，方便继续编辑
    if (mounted && !_focusNode.hasFocus) {
      FocusScope.of(context).requestFocus(_focusNode);
    }
    _imeBridge.syncSelectionToEditable();

    // 下一帧滚动确保可见
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (!mounted) return;
      _ensureCursorVisible();
    });

    setState(() {});
  }

  @override
  void initState() {
    super.initState();

    // 初始化文本缓冲与控制器
    buffer = TextBuffer();
    controller = EditorController(buffer: buffer, initPosition: 0);
    _textController = TextEditingController(text: buffer.getText());

    // 多击跟踪：用于双击选词/三击选行
    _multiClickTracker = MultiClickTracker(
      timeout: widget.config.multiClickTimeout,
      slop: widget.config.multiClickSlop,
      maxClicks: 3,
    );

    // 拖拽自动滚动
    _autoScroller = AutoScroller(
      margin: widget.config.autoScrollMargin,
      maxSpeed: widget.config.autoScrollMaxSpeed,
      tick: widget.config.autoScrollTick,
    );

    // 文本布局测量器（提供行高/边距/行号宽等参数）
    _textLayout = TextLayout(
      textStyle: _theme.base,
      lineHeight: _m.lineHeight,
      padding: _m.padding,
      lineNumberWidth: _m.lineNumberWidth,
    );

    // 光标闪烁：有焦点时可强制显示一帧
    _caretBlinker = CaretBlinker(period: widget.config.caretBlinkPeriod)
      ..addListener(() {
        if (mounted) setState(() {});
      })
      ..start();

    _focusNode.addListener(() {
      if (_focusNode.hasFocus) _caretBlinker.forceVisible();
    });

    // 输入法桥接：把 Editable 的改动同步回 buffer/controller
    _imeBridge = ImeBridge(
      buffer: buffer,
      controller: controller,
      textController: _textController,
      onAfterSync: () {
        if (!mounted) return;
        // 注意：不要重设 controller.value 以避免丢光标
        _onUserEdit();
        setState(() {});
        _ensureCursorVisible();
      },
    )..attach();

    // 监听外部文本（单向只读）变化
    widget.externalText?.addListener(_handleExternalTextChange);

    // 若构造时外部已存在初值，延后一帧加载
    final initial = widget.externalText?.value;
    if (initial != null) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (mounted) _loadText(initial);
      });
    }

    _ensureCursorVisible();
  }

  /// 用户编辑后的回调：推送到 externalText，并进行简单节流“自动保存”。
  void _onUserEdit() {
    final current = buffer.getText();
    final ext = widget.externalText;
    if (ext is ValueNotifier<String>) {
      ext.value = current; // 若上层用 ValueNotifier<String> 可直接双向同步
    }
    _autoSaveTimer?.cancel();
    _autoSaveTimer = Timer(const Duration(seconds: 1), () {
      // 这里可扩展实际的持久化逻辑（写文件/网络同步等）
    });
  }

  @override
  void didUpdateWidget(covariant CanvasEditor oldWidget) {
    super.didUpdateWidget(oldWidget);
    // externalText 发生更换时，迁移监听并加载其当前值
    if (oldWidget.externalText != widget.externalText) {
      oldWidget.externalText?.removeListener(_handleExternalTextChange);
      widget.externalText?.addListener(_handleExternalTextChange);
      final txt = widget.externalText?.value;
      if (txt != null) {
        WidgetsBinding.instance.addPostFrameCallback((_) {
          if (mounted) _loadText(txt);
        });
      }
    }
  }

  @override
  void dispose() {
    _autoSaveTimer?.cancel();
    _autoScroller.stop();
    _focusNode.dispose();
    _imeBridge.dispose();
    _textController.dispose();
    _multiClickTracker.reset();
    _caretBlinker.dispose();
    widget.externalText?.removeListener(_handleExternalTextChange);
    super.dispose();
  }

  /// 处理 Tab/Shift-Tab 缩进（不改变逻辑，仅包裹注释与同步 IME）。
  void _handleTab({required bool outdent}) {
    final value = _textController.value;
    final res = _indentService.indentOrOutdent(
      text: value.text,
      selection: value.selection,
      outdent: outdent,
      tabSpaces: widget.config.tabSpaces,
    );

    _textController.value = value.copyWith(
      text: res.text,
      selection: res.selection,
    );

    // 下一帧强制设置 selection 并同步到 Editable/IME
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _textController.selection = res.selection; // ★ 保证系统 selection 与内部一致
      _imeBridge.syncSelectionToEditable();
    });
  }

  /// 让光标立刻可见（重置闪烁计时）。
  void _forceCursorVisible() => _caretBlinker.forceVisible();

  /// 正在拖拽选择或自动滚动时，暂停自动“确保可见”逻辑，避免抖动。
  bool get _suspendEnsureVisible =>
      _sel.isSelecting || _autoScroller.isRunning;

  /// 计算并滚动到“光标可见”的位置（若必要）。
  void _ensureCursorVisible() {
    if (_suspendEnsureVisible) return;
    final lines = buffer.getLines();
    final double? target = _viewportScroller.computeScrollToReveal(
      cursorPosition: controller.cursorPosition,
      lines: lines,
      viewportHeight: _viewportHeight,
      currentScrollY: _scrollY,
      padding: _m.padding,
      lineHeight: _m.lineHeight,
    );
    if (target != null && target != _scrollY) {
      setState(() {
        _scrollY = target;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        _viewportHeight = constraints.maxHeight;

        // 局部函数：与 _ensureCursorVisible 等价，但基于最新 _viewportHeight
        void ensureCursorVisible() {
          if (_suspendEnsureVisible) return;
          final lines = buffer.getLines();
          final double? target = _viewportScroller.computeScrollToReveal(
            cursorPosition: controller.cursorPosition,
            lines: lines,
            viewportHeight: _viewportHeight,
            currentScrollY: _scrollY,
            padding: _m.padding,
            lineHeight: _m.lineHeight,
          );
          if (target != null && target != _scrollY) {
            setState(() => _scrollY = target);
          }
        }

        return EditorKeymap(
          onTab: () => _handleTab(outdent: false),
          onShiftTab: () => _handleTab(outdent: true),
          child: Stack(
            children: [
              // 主编辑表面：整合绘制、手势、滚动、命中测试等
              EditorSurface(
                buffer: buffer,
                controller: controller,
                metrics: _m,
                highlighter: _highlighter,
                theme: _theme,
                caretBlinker: _caretBlinker,
                focusNode: _focusNode,
                textLayout: _textLayout,
                multiClickTracker: _multiClickTracker,
                boundary: _boundary,
                autoScroller: _autoScroller,
                scrollY: _scrollY,
                viewportHeight: _viewportHeight,
                onScrollYChanged: (y) {
                  setState(() => _scrollY = y);
                },
                onSelectionChanged: (s, e) {
                  // 选区变更 -> 同步到 Editable（输入法）
                  _imeBridge.syncSelectionToEditable();
                },
                onCursorMoved: (_) {
                  _forceCursorVisible(); // 光标移动时立刻点亮
                  ensureCursorVisible(); // 计算必要滚动
                },
              ),
              // 隐藏的 Editable：用于系统 IME 交互（复制/粘贴/输入法）
              HiddenImeOverlay(
                controller: _textController,
                focusNode: _focusNode,
                onChanged: (_) => _imeBridge.syncSelectionToEditable(),
              ),
            ],
          ),
        );
      },
    );
  }
}
